package de.akabahn.ebd.fahrplan.io;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;

import de.akabahn.ebd.fahrplan.structure.Fahrplan;
import de.akabahn.ebd.fahrplan.structure.Station;
import de.akabahn.ebd.fahrplan.structure.Zuglauf;

/**
 * Class which implements the functionality to write .FPL files from given
 * Fahrplan objects
 * 
 * @author Chris
 * 
 */
public class FahrplanWriter {

    /**
     * Empty constructor
     */
    public FahrplanWriter() {

    }

    /**
     * Method for writing a .FPL file from a given Fahrplan
     * 
     * @param fpl
     *            the Fahrplan, which should be written
     * @param file
     *            String containing the filename and path
     * @throws IOException
     *             Exception which is thrown, if an IO error occured
     */
    public void writeFPLFile(Fahrplan fpl, String file) throws IOException {
	BufferedWriter bufWriter = new BufferedWriter(new FileWriter(file));

	// Iterator, which iterates over all zuglauefe of the Fahrplan
	for (Iterator<Zuglauf> it = fpl.getZuglaeufe().iterator(); it.hasNext();) {
	    Zuglauf current = it.next();
	    // Generation of the header
	    String zlHeader = generateZLHeader(current);
	    // Generation of all stations
	    String zlStations = generateZLStations(current);
	    bufWriter.write(zlHeader);
	    bufWriter.write(zlStations);
	}
	bufWriter.flush();
	bufWriter.close();
    }

    /**
     * Method for generating the header of a zuglauf
     * 
     * @param current
     *            Zuglauf for which the header should be generated
     * @return String containing the header
     */
    private String generateZLHeader(Zuglauf current) {
	String ausgabe = "";
	if (current.getNumber() != null)
	    ausgabe += generateHeaderLine("Zugnummer", current.getNumber());
	if (current.isWende()) {
	    ausgabe += generateHeaderLine("Wendezug", "1");
	} else {
	    ausgabe += generateHeaderLine("Wendezug", "0");
	}
	if (current.isReady()) {
	    ausgabe += generateHeaderLine("Fahrbereit", "1");
	} else {
	    ausgabe += generateHeaderLine("Fahrbereit", "0");
	}
	if (current.isPersonenZug()) {
	    ausgabe += generateHeaderLine("Personenzug", "1");
	} else {
	    ausgabe += generateHeaderLine("Personenzug", "0");
	}
	if (current.getUmlauf() != 0) {
	    ausgabe += generateHeaderLine("Umlauf",
		    Integer.toString(current.getUmlauf()));
	}
	if (current.getBaureihe() != 0) {
	    ausgabe += generateHeaderLine("Baureihe",
		    Integer.toString(current.getBaureihe()));
	}
	ausgabe += generateHeaderLine("Betriebstage", "XXXXXXX");
	if (current.getVmax() != 0) {
	    ausgabe += generateHeaderLine("Vmax",
		    Integer.toString(current.getVmax()));
	}
	if (current.getKommtAus() != null) {
	    ausgabe += generateHeaderLine("Wende aus", current.getKommtAus()
		    .getNumber());
	}
	if (current.getWirdZu() != null) {
	    ausgabe += generateHeaderLine("Wende auf", current.getWirdZu()
		    .getNumber());
	}
	return ausgabe;
    }

    /**
     * Method for writing a single FPL Zuglauf header line
     * 
     * @param key
     *            String header value key
     * @param value
     *            String header value according to the key
     * @return String containing the formatted header line
     */
    private String generateHeaderLine(String key, String value) {
	String ausgabe = key + ":\t" + value + "\n";
	return ausgabe;
    }

    /**
     * Method for generating the Stations for a given Zuglauf
     * 
     * @param current
     *            Zuglauf for which the stations should be generated
     * @return String containing the stations
     */
    private String generateZLStations(Zuglauf current) {
	StringBuffer ausgabe = new StringBuffer();

	for (Iterator<Station> it = current.getStationen().iterator(); it
		.hasNext();) {
	    Station currentStation = it.next();
	    String spezial = "";
	    if (currentStation.isWende())
		spezial = "W";
	    else if (currentStation.isDurchfahrt())
		spezial = "D";

	    ausgabe.append(currentStation.getBahnhof().getKurzbez() + "\t"
		    + currentStation.getAnkunft() + "\t"
		    + currentStation.getAbfahrt() + "\t");
	    ausgabe.append(spezial + "\t" + currentStation.getRegelgleis()
		    + "\t" + currentStation.getBahnhof().getGleiseAsString()
		    + "\t" + currentStation.getAufenthalt());
	    ausgabe.append("\n");
	}

	return ausgabe.toString();
    }

    /**
     * Method, which returns the FPL Code as a string to the caller
     * 
     * @param fpl
     *            Fahrplan, which should be printed
     * @return String containing a textual representation of the Fahrplan in the
     *         FPL format
     */
    public String outputFPLCode(Fahrplan fpl) {
	StringBuffer output = new StringBuffer();
	for (Iterator<Zuglauf> it = fpl.getZuglaeufe().iterator(); it.hasNext();) {
	    Zuglauf current = it.next();
	    String zlHeader = generateZLHeader(current);
	    String zlStations = generateZLStations(current);
	    output.append(zlHeader);
	    output.append(zlStations);
	}
	return output.toString();
    }

}
